#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <stdlib.h>
#include <cstring>
#include <mutex>
#include <thread>


pthread_cond_t cond;
pthread_mutex_t mtx;

void*mythread1(void*args)
{
    while(true)
    {
        pthread_cond_wait(&cond,&mtx);
        std::cout<<"I am running"<<std::endl;
    }
    return nullptr;
}

void*mythread2(void*args)
{
    while(true)
    {
        pthread_cond_signal(&cond);
        sleep(1);
    }
    return nullptr;
}
int main()
{
    pthread_t tid1,tid2;

    pthread_cond_init(&cond,nullptr);
    pthread_mutex_init(&mtx,nullptr);

    pthread_create(&tid1,nullptr,mythread1,nullptr);
    pthread_create(&tid2,nullptr,mythread2,nullptr);

    pthread_join(tid1,nullptr);
    pthread_join(tid2,nullptr);

    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cond);
    return 0;
}















// void Background()
// {
//     for (int i = 0; i < 5; i++)
//     {
//         std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠1s
//         std::cout << "Background thread running" << std::endl;
//     }
// }

// int main()
// {
//     std::thread t(Background);
//     t.detach(); // 分离线程，主线程无需等待

//     std::this_thread::sleep_for(std::chrono::seconds(2));

//     std::cout << "main thread quit" << std::endl;

//     return 0;
// }

// void mythread(int &a,int b)
// {
//     a+=b;
//     std::cout<<"mthread: a="<<a<<std::endl;

// }

// int main()
// {
//     int num=10;
//     std::thread t(mythread,std::ref(num),5);
//     if(t.joinable())
//     {
//         t.join();
//     }
//     std::cout<<"main thread:num"<<num<<std::endl;
//     return 0;
// }

// void mythread()
// {
//     std::cout<<"hello mythread"<<std::endl;
// }

// int main()
// {
//     std::thread t(mythread);
//     if(t.joinable())
//     {
//         t.join();
//     }
//     std::thread::id th_id=std::this_thread::get_id();
//     std::cout<<th_id<<std::endl;

//     std::cout<<std::this_thread::get_id()<<std::endl;

//     return 0;
// }

// pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;
// std::mutex mtx;
// int shared_data=0;
// int main()
// {
//     std::unique_lock<std::mutex> lock(mtx,std::defer_lock);
//     lock.lock();
//     shared_data++;
//     lock.unlock();
//     return 0;
// }

// int shared_data = 0;
// class LogMutex
// {
// public:
//     void lock()
//     {
//         std::cout << "lock被调用" << std::endl;
//         mtx.lock();
//     }
//     void unlock()
//     {
//         std::cout << "unlock被调用" << std::endl;
//         mtx.unlock();
//     }

// private:
//     std::mutex mtx;
// };

// int main()
// {
//     LogMutex log_mtx;
//     try{
//     // {
//         std::lock_guard<LogMutex> lock(log_mtx);
//         std::cout << "lock_guard已经创建" << std::endl;
//         std::cout << "执行临界区代码" << std::endl;
//         throw std::runtime_error("故意抛出异常");
//         shared_data++;
//         std::cout << "作用域结束" << std::endl;
//         shared_data++;
//     // }
//     }catch(const std::exception&e)
//     {
//         std::cout<<"捕捉到异常："<<e.what()<<std::endl;
//     }
//     return 0;
// }

// //定义两把互斥锁
// pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
// pthread_mutex_t lock2=PTHREAD_MUTEX_INITIALIZER;
// void*mythread1(void*args)
// {
//     pthread_mutex_lock(&lock1);
//     printf("mythread1:拿到lock1,等待lock2\n");
//     sleep(1); //故意延迟，让线程2有时间拿到lock2
//     pthread_mutex_lock(&lock2); //线程1等待lock2(被线程2持有)
//     printf("mythread1:拿到lock1");
//     pthread_mutex_unlock(&lock2);
//     pthread_mutex_unlock(&lock1);
//     return nullptr;
// }

// void*mythread2(void*args)
// {
//     pthread_mutex_lock(&lock2);
//     printf("mythread2:拿到lock2,等待lock1\n");
//     sleep(1); //故意延迟，让线程1有时间拿lock1
//     pthread_mutex_lock(&lock1);
//     printf("mythread1:拿到lock1");
//   pthread_mutex_unlock(&lock1);
//     pthread_mutex_unlock(&lock2);

//     return nullptr;
// }

// int main()
// {
//     pthread_t tid1,tid2;
//     pthread_create(&tid1,nullptr,mythread1,0);
//     pthread_create(&tid2,nullptr,mythread2,0);
//     pthread_join(tid1,nullptr);
//     pthread_join(tid2,nullptr);
//     return 0;
// }

// void*mythread(void*args)
// {
//     pthread_detach(pthread_self());
//     int i=0;
//     while(i<5)
//     {
//         std::cout<<"hello"<<std::endl;
//         sleep(1);
//         i++;
//     }
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,mythread,0);
//     if(pthread_join(tid,nullptr)==0)
//     {
//         std::cout<<"pthread_join success";
//     }
//     else
//     {
//         std::cout<<"pthread_join fail";
//     }
//     return 0;
// }

// void *mythread1(void *args)
// {
//     int *b = (int *)malloc(1024);
//     *b = 2;
//     pthread_exit((void *)b);
// }

// void *mythread2(void *args)
// {
//     int *a = (int *)malloc(1024);
//     *a = 10;
//     return (void *)a;
// }
// void *mythread3(void *args)
// {
//     while (true)
//     {
//         std::cout << "hello" << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;
//     void *ret;
//     pthread_create(&tid, nullptr, mythread1, 0);
//     pthread_join(tid, &ret);
//     printf("mythread1 return, thread id %X, return code:%d\n", tid, *(int *)ret);
//     free(ret);

//     pthread_create(&tid, nullptr, mythread2, 0);
//     pthread_join(tid, &ret);
//     printf("mythread2 return, thread id %X, return code:%d\n", tid, *(int *)ret);
//     free(ret);

//     pthread_create(&tid, nullptr, mythread3, 0);
//     sleep(4);
//     pthread_cancel(tid);
//     pthread_join(tid, &ret);

//     if (ret == PTHREAD_CANCELED)
//         printf("mythread3 return, thread id %X, return code:PTHREAD_CANCELED\n", tid);
//     else
//         printf("mythread3 return, thread id %X, return code:NULL\n", tid);

//     return 0;
// }

// void*mythread(void*args)
// {

//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;

//     pthread_create(&tid,nullptr,mythread,0);
//     std::cout<<"tid: "<<tid<<std::endl;
//     std::cout<<"pthread_self():"<<pthread_self()<<std::endl;;

//     return 0;
// }

// #define NUM 5
// int ticket = 1000;
// pthread_mutex_t mutex;

// class ThreadData
// {
// public:
//     ThreadData(int num)
//     {
//         _threadname = "thread-" + std::to_string(num);
//     }

//     // private:
// public:
//     std::string _threadname;
// };

// void *mythread(void *args)
// {
//     ThreadData *td = static_cast<ThreadData *>(args);
//     const char *name = td->_threadname.c_str();
//     while (true)
//     {
//         pthread_mutex_lock(&mutex);
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("%s,get a ticket:%d\n", name, ticket);
//             ticket--;
//             pthread_mutex_unlock(&mutex);
//             sched_yield();
//         }
//         else
//         {
//             pthread_mutex_unlock(&mutex);
//             break;
//         }
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_mutex_init(&mutex, nullptr);

//     std::vector<pthread_t> pids;
//     std::vector<ThreadData *> thread_datas;
//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_t pid;
//         ThreadData *td = new ThreadData(i);

//         thread_datas.push_back(td);
//         pthread_create(&pid, nullptr, mythread, thread_datas[i]);
//         pids.push_back(pid);
//     }
//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_join(pids[i], nullptr);
//     }
//     for (int i = 0; i < NUM; i++)
//     {
//         delete thread_datas[i];
//     }
//     pthread_mutex_destroy(&mutex);

//     return 0;
// }

// __thread int g_val=0;
// void*handler(void*args)
// {

//     while(true)
//     {
//         // g_val++;
//         std::cout<<"mypthread g_val: "<<g_val++<<",&g_val:"<<&g_val<<std::endl;
//         sleep(1);
//     }
// }
// int main()
// {
//     pthread_t pid;
//     pthread_create(&pid,nullptr,handler,0);
//     while(true)
//     {
//         // g_val++;
//         std::cout<<"main thread g_val: "<<g_val++<<",&g_val:"<<&g_val<<std::endl;
//         sleep(1);

//     }
//     pthread_join(pid,0);
//     return 0;
// }

// void *mythread(void *args)
// {
//     while (true)
//     {
//         std::cout << "i am mythread" << std::endl;
//         sleep(5);
//         int a = 10;
//         a /= 0;
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, mythread, 0);
//     while (true)
//     {
//         std::cout << "i am main pthread" << std::endl;
//         sleep(1);
//     }
//     pthread_join(tid,nullptr);
//     return 0;
// }

// void*mythread(void*args)
// {
//     int cnt=0;
//     while(cnt<10)
//     {
//         printf("hello ,i am pthread\n");
//         cnt++;
//         sleep(1);
//     }
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,mythread,0);
//     int cnt=0;
//     while(cnt<5)
//     {
//         printf("hello,i am main thread\n");
//         cnt++;
//         sleep(1);
//     }
//     void*retval;
//     pthread_join(tid,&retval);
//     std::cout<<"main thread quit,retval:"<<retval<<std::endl;
//     return 0;
// }